package com.av.db.layer.impl;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.av.db.dataobjects.Aclaracion;
import com.av.db.dataobjects.enums.EstatusAclaracion;
import com.av.db.layer.interfaces.AclaracionLayer;
import com.av.exceptions.AvException;

/**
 * Clase que contiene la implementacion de funciones para la tabla de
 * aclaraciones utilizando la tecnologia de Hibernate
 * 
 * @author Emmanuel Alcantara Garces
 * 
 */

public class AclaracionLayerImpl extends HibernateDaoSupport implements
		AclaracionLayer {

	private static Logger log = Logger.getLogger(AclaracionLayerImpl.class);

	/**
	 * Funcion que actualiza en la base de datos una aclaracion en especifico
	 */
	@Override
	public void actualizar(Aclaracion aclaracion) throws AvException {
		log.info("Inicio - actualizar(Aclaracion aclaracion)");
		log.debug(aclaracion.toString());

		if (aclaracion == null) {
			log.error("No se puede actualizar una aclaracion nula");
			throw new AvException("Aclaracion nula a ser actualizada");
		}

		if (aclaracion.getId() < 0) {
			log
					.error("No se puede actualizar una aclaracion con identificador "
							+ "invalido");
			throw new AvException(
					"Aclaracion con identificador invalido a ser "
							+ "actualizado");
		}

		getHibernateTemplate().update(aclaracion);

		log.info("Fin - actualizar(Aclaracion aclaracion)");
	}// actualizar

	/**
	 * Funcion que agrega en la base de datos configurada una nueva aclaracion
	 */
	@Override
	public void agregar(Aclaracion aclaracion) throws AvException {
		log.info("Inicio - agregar(Aclaracion aclaracion)");
		log.debug(aclaracion.toString());

		if (aclaracion == null) {
			log.error("No se puede agregar una aclaracion nula");
			throw new AvException("Aclaracion nula a ser agregada");
		}

		getHibernateTemplate().save(aclaracion);

		log.info("Fin - agregar(Aclaracion aclaracion)");
	}// agregar

	/**
	 * Funcion que elimina una aclaracion especifica de la base de datos
	 * configurada
	 */
	@Override
	public void eliminar(Aclaracion aclaracion) throws AvException {
		log.info("Inicio - eliminar(Aclaracion aclaracion)");
		log.debug(aclaracion.toString());

		if (aclaracion == null) {
			log.error("No se puede eliminar una aclaracion nula");
			throw new AvException("Aclaracion nula a ser eliminada");
		}

		if (aclaracion.getId() < 0) {
			log
					.error("No se puede eliminar una aclaracion con identificador negativo");
			throw new AvException("Identificador negativo");
		}

		getHibernateTemplate().delete(aclaracion);

		log.info("Fin - eliminar(Aclaracion aclaracion)");
	}// eliminar

	/**
	 * Funcion que obtiene una aclaracion de la base de datos configurada a
	 * partir de su identificador
	 */
	@Override
	public Aclaracion obtener(int id) {
		log.info("Inicio - obtener(int id)");
		log.debug("Id : " + id);

		if (id < 0) {
			log
					.warn("No se puede obtener una aclaracion con identificador negativo");
			return null;
		}

		Aclaracion tmp = getHibernateTemplate().get(Aclaracion.class, id);

		if (tmp != null) {
			log.debug("Aclaracion : " + tmp.toString());
		} else {
			log.debug("Aclaracion no encontrada");
		}

		log.info("Fin - obtener(int id)");

		return tmp;
	}// obtener

	/**
	 * Funcion que obtiene el conjunto de todos las aclaraciones registradas en
	 * la base de datos configurada
	 */
	@Override
	public Aclaracion[] obtener() {
		log.info("Inicio - obtener()");

		List<?> l = getSession().createCriteria(Aclaracion.class)
				.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).addOrder(
						Order.asc(Aclaracion.ID)).list();

		Aclaracion[] tmp = null;
		if (l != null && l.size() > 0) {
			log.debug("Cantidad obtenida : " + l.size());
			tmp = new Aclaracion[l.size()];
			l.toArray(tmp);
		}

		log.info("Fin - obtener()");

		return tmp;
	}// obtener

	/**
	 * Funcion que obtiene el conjunto de todas las aclaraciones registradas en
	 * la base de datos configurada para un estatusAclaracion especifico
	 */
	public Aclaracion[] obtener(EstatusAclaracion estatusAclaracion) {
		log.info("Inicio - obtener(EstatusAclaracion estatusAclaracion)");
		log.debug("EstatusAclaracion: " + estatusAclaracion);

		List<?> l = getSession().createCriteria(Aclaracion.class).add(
				Restrictions
						.eq(Aclaracion.ESTATUSACLARACION, estatusAclaracion))
				.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).addOrder(
						Order.asc(Aclaracion.ID)).list();

		Aclaracion[] tmp = null;
		if (l != null && l.size() > 0) {
			log.debug("Cantidad obtenida : " + l.size());
			tmp = new Aclaracion[l.size()];
			l.toArray(tmp);
		}
		log.info("Fin - obtener(EstatusAclaracion estatusAclaracion)");
		return tmp;
	}// obtenerCatalogo
}
